package de.homelabs.bookmarkmanager.desktop.qt.view;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Component;

import spiffy.log4j.LoggerHelper;

import com.trolltech.qt.gui.QMainWindow;

import de.homelabs.bookmarkmanager.desktop.qt.menu.HAction;
import de.homelabs.bookmarkmanager.desktop.qt.menu.HMenu;
import de.homelabs.bookmarkmanager.desktop.qt.menu.HMenuManager;
import de.homelabs.bookmarkmanager.service.IHContextMenuHandler;
import de.homelabs.utils.DateTimeUtils;
import de.homelabs.xml.menu.Menu;
import de.homelabs.xml.menu.MenuActionEntry;
import de.homelabs.xml.menu.RootMenuEntry;
import de.homelabs.xml.menu.parser.IMenuParser;

@Component
public class BookmarkManagerMainView extends QMainWindow {

	//constants
	private static final Logger logger = LoggerHelper.getLogger();
	private static final int MIN_WIDTH 				= 500;
	private static final int MIN_HEIGHT				= 300;
	
	//vars
	/*
	@Autowired
	private MainViewActionHandler mainViewActionHandler;
	*/
	@Autowired
	private HMenuManager menuManager;
	
	@Autowired
	IMenuParser hJaxbParser;
	
	@Autowired
	@Qualifier("menuLableMessageSource")
	ReloadableResourceBundleMessageSource rb;
		
	@Autowired
	@Qualifier("bookmarkService")
	private IHContextMenuHandler bookmarkService;
	
	//references
	//private QWidget centralWidget = null;
	
	/**
	 * constructor
	 */
	public BookmarkManagerMainView(){
		//Achtung: beim zugriff auf autowired beans (mainViewActionHandler in initUI())
		//NPE -> keine initalisierung im konstruktor!!
		//initUI();
	}
	

	/**
	 * initalize user interface
	 */
	public void initUI(){
		logger.debug("initUI");
		//set size to min
		this.setMinimumHeight(MIN_HEIGHT);
		this.setMinimumWidth(MIN_WIDTH);
		
		//default menu
		initMenu();
		
		//add content
		try {
			setCentralWidget(new HMainWidget(bookmarkService, this));
		} catch (Exception e){
			System.out.println("Fehler: ");
		}
		
		//statusbar
		this.statusBar().setToolTip("This is the Statusbar");
		messageToStatusBar("Application startet", true);
		
		//test register 
		//mainViewActionHandler.registerTestAction();
	}
	
	/**
	 * init menu
	 */
	private void initMenu(){		
		
		//new approach
		//get menu parser -> jaxb
		try {
			//load menu
			Menu menu = hJaxbParser.parseMenuXml("*-menu.xml");
			//Collections.sort(menu.getMenuActionEntry());
			initRootMenuEntries(menu.getRootMenuEntry(), menuManager);
			initMenuActions(menu.getMenuActionEntry(), menuManager);
			menuManager.connectMenuToMenuBar(this.menuBar());
		} catch (Exception e){
			//log error
			logger.error(e.getMessage());
			//create minimal menu
			menuManager.addRootMenuEntry(new HMenu("Datei","fileMenu"));
			HAction a2 = new HAction("beenden");
			a2.setActionKey("appEnd");
			menuManager.addActionToRootMenu(a2, "fileMenu");
			menuManager.connectMenuToMenuBar(this.menuBar());
		}
	}
	
	/**
	 * add entries to root menu
	 * 
	 * @param List<RootMenuEntry> entries - Root menu entries
	 * @param HMenuManager manager - menumanager
	 */
	private void initRootMenuEntries(List<RootMenuEntry> entries, HMenuManager manager){
		List<HMenu> rootMenuList = new ArrayList<HMenu>();
		
		try {
			//loop entries
			for (RootMenuEntry entry : entries){
				
					//add to menu list
					HMenu hmenu = new HMenu(rb.getMessage(entry.getLableKey(), null, Locale.GERMAN), entry.getActionKey(), entry.getOrder());
					rootMenuList.add(hmenu);
			}
			
			//sort list
			Collections.sort(rootMenuList);
			
			//zum Menu hinzufuegen
			for (HMenu hmenu : rootMenuList)
				manager.addRootMenuEntry(hmenu);
		} catch(NoSuchMessageException e){
			logger.error("Error adding MenuItem: "+e);
		}
	}
	
	/**
	 * add action elements to root entries
	 * 
	 * @param List<MenuActionEntry> entries - action entries
	 * @param HMenuManager manager - menumanager
	 */
	private void initMenuActions(List<MenuActionEntry> entries, HMenuManager manager){
		List<HAction> actionList = new ArrayList<HAction>();
		
		try {
			//loop
			for (MenuActionEntry entry : entries){
					//action object
					HAction action = new HAction(rb.getMessage(entry.getLableKey(), null, Locale.GERMAN));
					action.setActionKey(entry.getActionKey());
					action.setOrder(entry.getOrder());
					action.setParentItem(entry.getParent());
					//add to list
					actionList.add(action);
			}
			
			//sortieren
			Collections.sort(actionList);
			
			//zum menu hinzufugen
			for (HAction action : actionList){
				if (!manager.addActionToRootMenu(action, action.getParentItem())){
					logger.error("Error adding entry to menu: "+action.getActionKey()+","+action.getParentItem());
				}
			}
		} catch(NoSuchMessageException e){
			logger.error("Error adding MenuItem: "+e);
		}
	}
	
	/**
	 * write a message to the statusbar with/without timestamp
	 * 
	 * @param message - messag to write
	 * @param withTimeStamp - flag for timestamp
	 */
	public void messageToStatusBar(String message, boolean withTimeStamp){
		if (withTimeStamp){
			this.statusBar().showMessage("["+DateTimeUtils.SD.format(Calendar.getInstance().getTime())+"] "+message);
		} else {
			this.statusBar().showMessage(message);
		}
	}
}
